/*
 * @Descripttion:
 * @version:
 * @Author: xiaozilai
 * @Date: 2022-11-07 09:29:35
 * @LastEditors: xiaozilai
 * @LastEditTime: 2022-11-07 10:20:42
 */
/*
 * @lc app=leetcode.cn id=816 lang=cpp
 *
 * [816] 模糊坐标
 *
 * https://leetcode.cn/problems/ambiguous-coordinates/description/
 *
 * algorithms
 * Medium (50.75%)
 * Likes:    71
 * Dislikes: 0
 * Total Accepted:    7.6K
 * Total Submissions: 13.6K
 * Testcase Example:  '"(123)"'
 *
 * 我们有一些二维坐标，如 "(1, 3)" 或 "(2,
 * 0.5)"，然后我们移除所有逗号，小数点和空格，得到一个字符串S。返回所有可能的原始字符串到一个列表中。
 *
 * 原始的坐标表示法不会存在多余的零，所以不会出现类似于"00", "0.0", "0.00", "1.0", "001",
 * "00.01"或一些其他更小的数来表示坐标。此外，一个小数点前至少存在一个数，所以也不会出现“.1”形式的数字。
 *
 * 最后返回的列表可以是任意顺序的。而且注意返回的两个数字中间（逗号之后）都有一个空格。
 *
 *
 *
 *
 * 示例 1:
 * 输入: "(123)"
 * 输出: ["(1, 23)", "(12, 3)", "(1.2, 3)", "(1, 2.3)"]
 *
 *
 *
 * 示例 2:
 * 输入: "(00011)"
 * 输出:  ["(0.001, 1)", "(0, 0.011)"]
 * 解释:
 * 0.0, 00, 0001 或 00.01 是不被允许的。
 *
 *
 *
 * 示例 3:
 * 输入: "(0123)"
 * 输出: ["(0, 123)", "(0, 12.3)", "(0, 1.23)", "(0.1, 23)", "(0.1, 2.3)",
 * "(0.12, 3)"]
 *
 *
 *
 * 示例 4:
 * 输入: "(100)"
 * 输出: [(10, 0)]
 * 解释:
 * 1.0 是不被允许的。
 *
 *
 *
 *
 * 提示:
 *
 *
 * 4 <= S.length <= 12.
 * S[0] = "(", S[S.length - 1] = ")", 且字符串 S 中的其他元素都是数字。
 *
 *
 *
 *
 */

// @lc code=start
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
    vector<string> ambiguousCoordinates(string s) {
        vector<string> ans;
        int n = s.length();
        n -= 2;
        for (int i = 1; i < n; ++i) {
            helper(s.substr(1, i), s.substr(i + 1, n - i), ans);
        }
        return ans;
    }

    void helper(string s1, string s2, vector<string> &ans) {
        int length_1 = s1.length(), length_2 = s2.length();
        for (int i = 1; i <= length_1; ++i) {
            for (int j = 1; j <= length_2; ++j) {
                bool fracExisted_1 = false;
                bool fracExisted_2 = false;
                string s1_1 = s1.substr(0, i);
                string s1_2{};
                string s2_1 = s2.substr(0, j);
                string s2_2{};
                if (i < length_1) {
                    fracExisted_1 = true;
                    s1_2 = s1.substr(i);
                }
                if (j < length_2) {
                    fracExisted_2 = true;
                    s2_2 = s2.substr(j);
                }
                bool isValid_1 = fracExisted_1 ? isRound(s1_1) && isFractional(s1_2) : isRound(s1_1);
                bool isValid_2 = fracExisted_2 ? isRound(s2_1) && isFractional(s2_2) : isRound(s2_1);
                if (isValid_1 && isValid_2) {
                    ans.push_back("(" + (fracExisted_1 ? s1_1 + "." + s1_2 : s1_1) + ", " + (fracExisted_2 ? s2_1 + "." + s2_2 : s2_1) + ")");
                }
            }
        }
    }

    bool isRound(string s) {
        if (!s.empty() && ((s.length() != 1 && s[0] != '0') || s.length() == 1)) {
            return true;
        }
        return false;
    }

    bool isFractional(string s) {
        if (!s.empty() && s.back() != '0') {
            return true;
        }
        return false;
    }
};
// @lc code=end
